package com.dragon.logical.service.contract.impl;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.common.util.DateNumUtils;
import com.dragon.common.util.JwtUtil;
import com.dragon.common.util.StringUtils;
import com.dragon.logical.service.contract.ProduceService;
import com.dragon.logical.service.customer.CustomerService;
import com.dragon.repository.entity.*;
import com.dragon.repository.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 生产表 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-06-25
 */
@Service
public class ProduceServiceImpl extends ServiceImpl<ProduceMapper, Produce> implements ProduceService {

    @Autowired
    ProduceMapper produceMapper;
    @Autowired
    ProduceProductsMapper ppMapper;
    @Autowired
    AdminDepartmentMapper adMapper;
    @Autowired
    AdminMapper adminMapper;
    @Autowired
    ContractMapper contractMapper;
    @Autowired
    DeliverMapper deliverMapper;
    @Autowired
    AdminDepartmentMapper adminDepartmentMapper;
    @Autowired
    PlanCollectMapper planCollectMapper;
    @Autowired
    OtherFileMapper fileMapper;
    @Autowired
    CustomerMapper customerMapper;
    @Autowired
    QuotesMapper quotesMapper;
    @Autowired
    CustomerService customerService;
    @Autowired
    OtherFileMapper otherFileMapper;


    @Override
    public Page<Produce> listProduce(String search, Integer page, Integer limit, Integer type,
                                     Integer status,String customerName, Integer businessAdminId,
                                     String startTime, String endTime
                                     ) {
        Page<Produce> producePage = new Page<>(page, limit);
        QueryWrapper<Produce> wrapper = new QueryWrapper<>();
        wrapper.eq(type != null,"M.type",type)
                .eq( "M.status", 1)
                .like(StrUtil.isNotBlank(customerName),"M.customerName", customerName)
                .eq(businessAdminId!=null,"M.admin_id",businessAdminId)
                .ge(StrUtil.isNotBlank(startTime),"M.create_time", startTime)
                .le(StrUtil.isNotBlank(endTime), "M.create_time", endTime)
                .orderByDesc("M.create_time");
        return produceMapper.selectProduce(producePage, wrapper);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addProduce(Produce convert) {

        //自动生成编号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String code = "SC-" + sdf.format(DateUtil.date());
        String maxCode =  produceMapper.maxRoundInoutNumber(code);
        String newCode = null;
        if (StrUtil.isEmpty(maxCode)){
            newCode = code + "001";
        }
        else {
            String getMaxCode = maxCode.substring(11, 14);
            newCode = code + DateNumUtils.getNum(getMaxCode);
        }
        convert.setNumber(newCode);
        convert.setCreateTime(DateUtil.date());
        convert.setStatus(1);
        //添加生产主表信息
        produceMapper.insert(convert);

        //添加生产子表信息
        convert.getProduceProducts().forEach(produceProducts -> {
            produceProducts.setProduceId(convert.getId());
            ppMapper.insert(produceProducts);
        });
    }

    @Override
    public void updateProduce(Produce produce) {
        Produce pro = produceMapper.selectById(produce.getId());
        if (pro == null) {
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        produce.setUpdateTime(DateUtil.date());
        produceMapper.updateById(produce);
    }

    @Override
    public void deleteProduce(List<Integer> ids) {
        List<Produce> produces = produceMapper.selectBatchIds(ids);
        if (produces.size() != ids.size()) {
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        ids.forEach( id -> {
            customerService.deleteThorough(3,id);
        });
        produceMapper.deleteBatchIds(ids);
    }

    @Override
    public List<Produce> selectListContractId(Integer id) {
        List<Produce> produces = produceMapper.selectProduceByContractId(id);
        return produces;
    }

    @Override
    public Produce selectProduceById(Integer id) {
        Produce produces = produceMapper.selectProduceById(id);
        if (produces == null){
            produces = new Produce();
        } else {
            List<OtherFile> otherFileList = fileMapper.selectList(new QueryWrapper<OtherFile>().lambda()
                    .eq(OtherFile::getStreamType, 3).eq(OtherFile::getCorrelationId, id));
            if (otherFileList.size() != 0 ){
                produces.setOtherFileList(otherFileList);
            }
            List<ProduceProducts> produceProducts = ppMapper.selectListByProduceId(id);
            if (produceProducts.size() !=0 ){
                produces.setProduceProducts(produceProducts);
            }
        }
        return produces;
    }

    @Override
    public void changeProduceType(Integer id, Integer type) {
        Produce produce = produceMapper.selectById(id);
        produce.setType(type);
        produce.setUpdateTime(DateUtil.date());
        produceMapper.updateById(produce);
        QueryWrapper<ProduceProducts> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ProduceProducts::getProduceId, id);
        List<ProduceProducts> produceProducts = ppMapper.selectList(wrapper);
        if(produceProducts.size()==0||produceProducts==null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        produceProducts.forEach(pp -> {
            pp.setProduceStatus(type);
            ppMapper.updateById(pp);
        });
        // 生成对应配送单子
        if (type == 2) {
            generateData(produce);
        }
    }


    @Override
    public void generateData(Produce produce){
        Contract contract = contractMapper.selectById(produce.getContractId());
        //查询送货人上级部门
        QueryWrapper<AdminDepartment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(AdminDepartment::getAdminId, contract.getDeliveryOfficer(), contract.getPayee());
        List<AdminDepartment> adminDepartment = adminDepartmentMapper.selectList(queryWrapper);
        Integer deliverDepartment = adminDepartment.stream().filter(e -> e.getAdminId().equals(contract.getDeliveryOfficer())).findFirst().get().getDepartmentId();
        // 生成配送单
        Deliver deliver = new Deliver();
        deliver.setProduceId(produce.getId());
        deliver.setContractId(produce.getContractId());
        deliver.setCreateTime(DateUtil.date());
        deliver.setDeliveryId(contract.getDeliveryOfficer());
        deliver.setDepartmentId(deliverDepartment);
        deliver.setAdminId(produce.getAdminId());
        deliver.setCustomerId(contract.getCustomerId());
        deliver.setAddress(contract.getAddress());
        deliverMapper.insert(deliver);
        //预付款组合方式
        if (contract.getPaymentMethod() == 1 && contract.getCombination() == 3) {
            Integer planDepartment = adminDepartment.stream().filter(e -> e.getAdminId().equals(contract.getPayee())).findFirst().get().getDepartmentId();
            PlanCollect planCollect = new PlanCollect();
            planCollect.setContractId(contract.getId());
            planCollect.setCreateTime(DateUtil.date());
            planCollect.setAdminId(contract.getPayee());
            planCollect.setPlanMoney(contract.getMoney() - contract.getPrepaymentMoney());
            planCollect.setDepartmentId(planDepartment);
            planCollect.setPlanTime(contract.getAgreeTime());
            planCollectMapper.insert(planCollect);
        }
    }

    @Override
    public Map<String, Object> newProduceNum(HttpServletRequest request, Integer adminId) {
        String authCode = JwtUtil.getAuthCode(request);
        String departmentIds = JwtUtil.getDepartmentIds(request);
        Integer accountType = JwtUtil.getIsAdmin(request);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String time = sdf.format(new Date());

        List<Produce> produces = new ArrayList<>();
        List<Produce> produceList = produceMapper.selectList(null);
        //判断是否为管理员
        if (accountType == 1) {
            produces = produceMapper.selectListByTime(time, null, null);
            //判断是否本人
        } else if (authCode.equals("1")) {
            produces = produceMapper.selectListByTime(time, null, adminId);
            // 判断部门权限
        } else if (authCode.equals("2") || authCode.equals("3") || authCode.equals("4")) {
            //List<Integer> departmentSet = Stream.of(departmentIds.split(",")).map(Integer::valueOf).collect(Collectors.toList());
            List<String> departmentSet = Arrays.asList(departmentIds.split(","));
            produces = produceMapper.selectListByTime(time, departmentSet, null);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("total", produces.size());
        map.put("monthTotal", produceList.size());
        return map;
    }

    @Override
    public String getAddress(Integer produceId) {
        Produce produce = produceMapper.selectAddress(produceId);
        if (StrUtil.isNotBlank(produce.getContractAddress())){
            return produce.getContractAddress();
        } else {
            Customer customer = customerMapper.selectById(produce.getCustomerId());
            return customer.getAddress();
        }
    }

    @Override
    public Map<String, Object> statistics() {
        Map<String, Object> map = new HashMap<>();
        // 生产 年数量
        Long productYearNum = produceMapper.selectYearProduceCount();
        map.put("productYearNum", productYearNum);
        // 生产 月数量
        Long productMonthNum = produceMapper.selectMonthProduceCount();
        map.put("produceMonthNum", productMonthNum);
        //送货 年数量
        Long deliverYearNum = deliverMapper.selectYearDeliverCount();
        map.put("deliverYearNum", deliverYearNum);
        //送货 月数量
        Long deliverMonthNum = deliverMapper.selectMonthDeliverCount();
        map.put("deliverMonthNum", deliverMonthNum);
        return map;
    }

    @Override
    public Produce selectProduceByContractId(Integer contractId) {
        Produce produce = produceMapper.selectDetailByContractId(contractId);
        if (produce == null) {
            produce = new Produce();
        } else {
            List<OtherFile> otherFileList = fileMapper.selectList(new QueryWrapper<OtherFile>().lambda()
                    .eq(OtherFile::getStreamType, 3).eq(OtherFile::getCorrelationId, produce.getId()));
            if (otherFileList.size() != 0) {
                produce.setOtherFileList(otherFileList);
            }
            List<ProduceProducts> produceProducts = ppMapper.selectListByProduce(null,produce.getId());
            if (produceProducts.size() != 0) {
                produce.setProduceProducts(produceProducts);
            } else {
                produceProducts = new ArrayList<>();
                produce.setProduceProducts(produceProducts);
            }
            return produce;
        }
        return produce;
    }

    @Override
    public List<OtherFile> getContractOtherFileByProduceId(Integer produceId) {
        Produce produce = produceMapper.selectById(produceId);
        Contract contract = contractMapper.selectById(produce.getContractId());
        QueryWrapper<OtherFile> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(OtherFile::getStreamType,2)
                .eq(OtherFile::getCorrelationId, contract.getId())
                .eq(OtherFile::getFileType,1);
        List<OtherFile> otherFileList = otherFileMapper.selectList(wrapper);
        return otherFileList;
    }
}
